package site.isscloud.project.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import site.isscloud.project.domain.DeviceChannel;
import site.isscloud.project.domain.PjRealtimeTemperatureData;
import site.isscloud.project.domain.TemperatureOverview;
import site.isscloud.project.mapper.PjRealtimeTemperatureDataMapper;
import site.isscloud.project.mqtt.dto.TemperatureMqttDto;
import site.isscloud.project.service.IPjRealtimeTemperatureDataIssueService;
import site.isscloud.project.service.IPjRealtimeTemperatureService;
import site.isscloud.project.constants.BusinessConstants;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PjRealtimeTemperatureServiceImpl implements IPjRealtimeTemperatureService {

    private static final Logger log = LoggerFactory.getLogger(PjRealtimeTemperatureServiceImpl.class);

    @Autowired
    private PjRealtimeTemperatureDataMapper temperatureDataMapper;

    // 在 PjRealtimeTemperatureServiceImpl 中添加以下方法

    @Autowired
    private IPjRealtimeTemperatureDataIssueService temperatureDataIssueService;


    @Override
    public void processMqttTemperatureData(TemperatureMqttDto mqttData) {
        try {
            log.info("开始处理MQTT温度数据 - 设备: {}, 通道: {}",
                    mqttData.getDeviceNo(), mqttData.getChannelNo());

            // 1. 存储实时温度数据
            PjRealtimeTemperatureData realtimeData = saveRealtimeTemperatureData(mqttData);

            // 2. 检测异常温度并存储异常数据
            detectAndSaveAbnormalTemperatures(mqttData, realtimeData);

            log.debug("MQTT温度数据处理完成 - 设备: {}, 通道: {}",
                    mqttData.getDeviceNo(), mqttData.getChannelNo());

        } catch (Exception e) {
            log.error("处理MQTT温度数据失败 - 设备: {}, 通道: {}",
                    mqttData.getDeviceNo(), mqttData.getChannelNo(), e);
            throw new RuntimeException("处理MQTT温度数据失败", e);
        }
    }

    @Override
    public Integer[] getMeterRangeByDeviceChannel(String deviceNo, Integer channelNo) {
        // 复用现有的 getDeviceChannels 方法
        List<DeviceChannel> deviceChannels = getDeviceChannels();

        for (DeviceChannel channel : deviceChannels) {
            if (channel.getDeviceNo().equals(deviceNo) &&
                    channel.getChannelNo().equals(channelNo)) {
                return new Integer[]{
                        channel.getStartMeter(),
                        channel.getEndMeter()
                };
            }
        }

        // 如果静态配置中没有找到，尝试从数据库查询
        List<DeviceChannel> dbChannels = selectDistinctDeviceChannels();
        for (DeviceChannel channel : dbChannels) {
            if (channel.getDeviceNo().equals(deviceNo) &&
                    channel.getChannelNo().equals(channelNo)) {
                return new Integer[]{
                        channel.getStartMeter(),
                        channel.getEndMeter()
                };
            }
        }

        log.warn("未找到设备 {} 通道 {} 的米标范围配置", deviceNo, channelNo);
        // 如果没有找到配置，返回默认范围
        return new Integer[]{1, 1500}; // 默认范围，移除了对 mqttData 的引用
    }

    /**
     * 存储实时温度数据 - 复用现有的数据存储逻辑
     */
    private PjRealtimeTemperatureData saveRealtimeTemperatureData(TemperatureMqttDto mqttData) {
        PjRealtimeTemperatureData realtimeData = new PjRealtimeTemperatureData();
        realtimeData.setDeviceNo(mqttData.getDeviceNo());
        realtimeData.setChannelNo(mqttData.getChannelNo());

        // 获取设备通道的米标范围
        Integer[] meterRange = getMeterRangeByDeviceChannel(mqttData.getDeviceNo(), mqttData.getChannelNo());
        realtimeData.setStartMeter(meterRange[0].doubleValue());
        realtimeData.setEndMeter(meterRange[1].doubleValue());

        // 转换温度列表为字符串格式（与现有格式保持一致）
        String maxTempsStr = convertTemperaturesToString(mqttData.getMaxTemperatures());
        String minTempsStr = convertTemperaturesToString(mqttData.getMinTemperatures());

        realtimeData.setMaxTemperatures(maxTempsStr);
        realtimeData.setMinTemperatures(minTempsStr);
        realtimeData.setCreateTime(new Date());

        // 使用新添加的插入方法
        int result = insertPjRealtimeTemperatureData(realtimeData);

        if (result > 0) {
            log.debug("实时温度数据存储成功 - ID: {}", realtimeData.getId());
        } else {
            log.error("实时温度数据存储失败");
            throw new RuntimeException("实时温度数据存储失败");
        }

        return realtimeData;
    }

    /**
     * 转换温度列表为JSON字符串格式
     */
    private String convertTemperaturesToString(List<BigDecimal> temperatures) {
        try {
            // 将 List<BigDecimal> 转换为 JSON 数组字符串
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(temperatures);
        } catch (Exception e) {
            log.error("转换温度数据为JSON失败", e);
            // 备用方案：手动构建JSON数组
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < temperatures.size(); i++) {
                if (i > 0) {
                    sb.append(",");
                }
                sb.append(temperatures.get(i));
            }
            sb.append("]");
            return sb.toString();
        }
    }

    /**
     * 检测并存储异常温度数据
     */
    private void detectAndSaveAbnormalTemperatures(TemperatureMqttDto mqttData, PjRealtimeTemperatureData realtimeData) {
        double abnormalThreshold = BusinessConstants.ABNORMAL_TEMP_ABSOLUTE_THRESHOLD; // 异常温度阈值

        List<BigDecimal> maxTemperatures = mqttData.getMaxTemperatures();
        Integer[] meterRange = getMeterRangeByDeviceChannel(mqttData.getDeviceNo(), mqttData.getChannelNo());
        int startMeter = meterRange[0];

        for (int i = 0; i < maxTemperatures.size(); i++) {
            BigDecimal temperature = maxTemperatures.get(i);

            // 检测异常温度
            if (temperature.doubleValue() > abnormalThreshold) {
                int meterPosition = startMeter + i;

                // 存储异常温度数据
                temperatureDataIssueService.saveAbnormalTemperatureData(
                        mqttData.getDeviceNo(),
                        mqttData.getChannelNo(),
                        meterPosition,
                        temperature,
                        mqttData.getMinTemperatures().get(i),
                        new Date()
                );

                log.info("检测到异常温度 - 设备: {}, 通道: {}, 米标: {}, 温度: {}",
                        mqttData.getDeviceNo(), mqttData.getChannelNo(),
                        meterPosition, temperature);
            }
        }
    }

    @Override
    public List<DeviceChannel> getDeviceChannels() {
        List<DeviceChannel> list1 = new ArrayList<>();

        // 设备001，通道1：米标1-1500
        DeviceChannel device1 = new DeviceChannel();
        device1.setDeviceNo("001");
        device1.setChannelNo(1);
        device1.setStartMeter(1);
        device1.setEndMeter(1500);
        list1.add(device1);

        // 设备001，通道2：米标1601-2840
        DeviceChannel device2 = new DeviceChannel();
        device2.setDeviceNo("001");
        device2.setChannelNo(2);
        device2.setStartMeter(1601);
        device2.setEndMeter(2840);
        list1.add(device2);

        return list1;
    }

    @Override
    public List<DeviceChannel> selectDistinctDeviceChannels() {
        return temperatureDataMapper.selectDistinctDeviceChannels();
    }

    @Override
    public TemperatureOverview getTemperatureOverview() {
        TemperatureOverview overview = temperatureDataMapper.selectTemperatureOverview();
        if (overview == null) {
            // 如果查询不到数据，返回默认值
            overview = new TemperatureOverview();
            overview.setDeviceCount(0);
            overview.setChannelCount(0);
            overview.setMeterCount(0);
            overview.setMaxTemperature(0.0);
            overview.setMinTemperature(0.0);
            overview.setAvgTemperature(0.0);
            overview.setAlarmCount(0);
        }
        return overview;
    }

    @Override
    public List<PjRealtimeTemperatureData> getRealtimeTemperatureData(String deviceNo, Integer channelNo) {
        // 获取当前时间的前一分钟数据
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneMinuteAgo = now.minusMinutes(1);
        String statTime = oneMinuteAgo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:00"));

        List<PjRealtimeTemperatureData> dataList = temperatureDataMapper.selectMinuteRealtimeData(deviceNo, channelNo, statTime);

        // 如果查询不到指定分钟的数据，获取最新数据
        if (dataList.isEmpty()) {
            PjRealtimeTemperatureData latestData = temperatureDataMapper.selectLatestTemperatureData(deviceNo, channelNo);
            if (latestData != null) {
                dataList.add(latestData);
            }
        }

        // 处理温度数组，转换为前端需要的格式
        return processTemperatureData(dataList);
    }

    @Override
    public List<PjRealtimeTemperatureData> getTemperatureTrendData(String deviceNo, Integer channelNo,
                                                         String startTime, String endTime,
                                                         String timeType) {
        List<PjRealtimeTemperatureData> dataList = temperatureDataMapper.selectTemperatureDataByTimeRange(
                deviceNo, channelNo, startTime, endTime);
        return processTemperatureData(dataList);
    }

    @Override
    public List<PjRealtimeTemperatureData> getMeterRangeTemperatureData(String deviceNo, Integer channelNo,
                                                              Integer startMeter, Integer endMeter) {
        // 获取最新数据并截取指定米标范围
        List<PjRealtimeTemperatureData> allData = getRealtimeTemperatureData(deviceNo, channelNo);
        if (allData.isEmpty()) {
            return new ArrayList<>();
        }

        // 取第一条数据（最新数据）并截取指定米标范围
        PjRealtimeTemperatureData latestData = allData.get(0);
        return extractMeterRangeData(latestData, startMeter, endMeter);
    }

    @Override
    public PjRealtimeTemperatureData getLatestTemperatureData(String deviceNo, Integer channelNo) {
        List<PjRealtimeTemperatureData> dataList = getRealtimeTemperatureData(deviceNo, channelNo);
        return dataList.isEmpty() ? null : dataList.get(0);
    }

    @Override
    public int insertPjRealtimeTemperatureData(PjRealtimeTemperatureData pjRealtimeTemperatureData) {
        return temperatureDataMapper.insertPjRealtimeTemperatureData(pjRealtimeTemperatureData);
    }

    @Override
    public int batchInsertPjRealtimeTemperatureData(List<PjRealtimeTemperatureData> pjRealtimeTemperatureDataList) {
        return temperatureDataMapper.batchInsertPjRealtimeTemperatureData(pjRealtimeTemperatureDataList);
    }

    /**
     * 处理温度数据，将JSON数组字符串转换为列表
     */
    private List<PjRealtimeTemperatureData> processTemperatureData(List<PjRealtimeTemperatureData> dataList) {
        for (PjRealtimeTemperatureData data : dataList) {
            // 解析JSON数组字符串为Double列表
            List<Double> maxTemps = parseTemperatureArray(data.getMaxTemperatures());
            List<Double> minTemps = parseTemperatureArray(data.getMinTemperatures());

            data.setMaxTemperatureList(maxTemps);
            data.setMinTemperatureList(minTemps);
        }
        return dataList;
    }

    /**
     * 解析温度数组JSON字符串
     */
    private List<Double> parseTemperatureArray(String temperatureArray) {
        List<Double> result = new ArrayList<>();
        if (temperatureArray != null && !temperatureArray.isEmpty()) {
            // 移除JSON数组的方括号
            String cleanArray = temperatureArray.replace("[", "").replace("]", "");
            String[] tempValues = cleanArray.split(",");
            for (String temp : tempValues) {
                try {
                    result.add(Double.parseDouble(temp.trim()));
                } catch (NumberFormatException e) {
                    result.add(0.0);
                }
            }
        }
        return result;
    }

    /**
     * 提取指定米标范围的温度数据
     */
    private List<PjRealtimeTemperatureData> extractMeterRangeData(PjRealtimeTemperatureData sourceData,
                                                        Integer startMeter, Integer endMeter) {
        List<PjRealtimeTemperatureData> result = new ArrayList<>();

        if (sourceData == null || startMeter == null || endMeter == null) {
            return result;
        }

        // 创建新的温度数据对象
        PjRealtimeTemperatureData rangeData = new PjRealtimeTemperatureData();
        rangeData.setCreateTime(sourceData.getCreateTime());
        rangeData.setDeviceNo(sourceData.getDeviceNo());
        rangeData.setChannelNo(sourceData.getChannelNo());
        rangeData.setStartMeter(sourceData.getStartMeter());
        rangeData.setEndMeter(sourceData.getEndMeter());

        // 截取指定范围的温度数据
        List<Double> maxTemps = sourceData.getMaxTemperatureList();
        List<Double> minTemps = sourceData.getMinTemperatureList();

        if (maxTemps != null && minTemps != null &&
                maxTemps.size() == minTemps.size() &&
                startMeter >= 1 && endMeter <= maxTemps.size() && startMeter <= endMeter) {

            List<Double> rangeMaxTemps = new ArrayList<>();
            List<Double> rangeMinTemps = new ArrayList<>();

            for (int i = startMeter - 1; i < endMeter; i++) {
                rangeMaxTemps.add(maxTemps.get(i));
                rangeMinTemps.add(minTemps.get(i));
            }

            rangeData.setMaxTemperatureList(rangeMaxTemps);
            rangeData.setMinTemperatureList(rangeMinTemps);
            result.add(rangeData);
        }

        return result;
    }
}